{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "fbf0958d",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import lightgbm as lgb\n",
    "from sklearn.model_selection import StratifiedKFold, KFold\n",
    "from sklearn.metrics import mean_squared_error\n",
    "from lightgbm import *\n",
    "import optuna\n",
    "#from autoviz.AutoViz_Class import AutoViz_Class\n",
    "#import xgboost as xgb\n",
    "from xgboost import *\n",
    "#import matplot.pyplot\n",
    "%matplotlib inline\n",
    "#plt.rcParams['font.sans-serif'] = ['SimHei']  # Windows系统\n",
    "#plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']  # Mac系统\n",
    "#plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "93455a61",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 读取数据\n",
    "train_df = pd.read_csv('train.csv')\n",
    "test_df = pd.read_csv('test.csv')\n",
    "df_all=pd.concat([train_df,test_df])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "599c67d1",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/root/miniconda3/lib/python3.8/site-packages/pandas/core/arraylike.py:396: RuntimeWarning: invalid value encountered in log1p\n",
      "  result = getattr(ufunc, method)(*inputs, **kwargs)\n"
     ]
    }
   ],
   "source": [
    "def feature_engineering(df):\n",
    "    # 基础特征\n",
    "    #features = df.drop(['id', 'BeatsPerMinute'], axis=1, errors='ignore')\n",
    "    features=df.copy()\n",
    "    # 衍生特征\n",
    "    features['EnergyRhythmRatio'] = df['Energy'] / (df['RhythmScore'] + 1e-6)\n",
    "    features['VocalAcousticRatio'] = df['VocalContent'] / (df['AcousticQuality'] + 1e-6)\n",
    "    features['DurationMinutes'] = df['TrackDurationMs'] / 60000\n",
    "    features['MoodEnergyRatio'] = df['MoodScore'] / (df['Energy'] + 1e-6)\n",
    "    features['LiveInstRatio'] = df['LivePerformanceLikelihood'] / (df['InstrumentalScore'] + 1e-6)\n",
    "    \n",
    "    # 对数变换\n",
    "    for col in ['AudioLoudness', 'TrackDurationMs']:\n",
    "        features[f'log_{col}'] = np.log1p(df[col])\n",
    "    \n",
    "    return features\n",
    "\n",
    "df_all=feature_engineering(df_all)\n",
    "train_df,test_df=df_all[:len(train_df)],df_all[len(train_df):]\n",
    "\n",
    "feature_selected=[c for c in df_all.columns if c not in ['id', 'BeatsPerMinute']]\n",
    "# 准备训练数据\n",
    "X_train = train_df[feature_selected]\n",
    "y_train = train_df['BeatsPerMinute']\n",
    "X_test =  test_df[feature_selected]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "8bea67a3",
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'X_train' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m~\\AppData\\Local\\Temp\\ipykernel_64388\\4225672638.py\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mX_train\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m: name 'X_train' is not defined"
     ]
    }
   ],
   "source": [
    "X_train.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "1ddf8a25-bf6e-477a-828e-452449969c81",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[I 2025-09-26 11:14:29,191] A new study created in memory with name: no-name-29b4e392-ef53-4dfb-bf03-1a0bb81545a2\n",
      "[I 2025-09-26 11:14:45,584] Trial 0 finished with value: 26.461018849487466 and parameters: {'max_depth': 8, 'min_child_weight': 19}. Best is trial 0 with value: 26.461018849487466.\n",
      "[I 2025-09-26 11:15:01,962] Trial 1 finished with value: 26.461255785560486 and parameters: {'max_depth': 8, 'min_child_weight': 9}. Best is trial 0 with value: 26.461018849487466.\n",
      "[I 2025-09-26 11:15:22,866] Trial 2 finished with value: 26.46157031800322 and parameters: {'max_depth': 9, 'min_child_weight': 7}. Best is trial 0 with value: 26.461018849487466.\n",
      "[I 2025-09-26 11:15:44,481] Trial 3 finished with value: 26.461555691597404 and parameters: {'max_depth': 9, 'min_child_weight': 5}. Best is trial 0 with value: 26.461018849487466.\n",
      "[I 2025-09-26 11:15:56,989] Trial 4 finished with value: 26.460696860795544 and parameters: {'max_depth': 3, 'min_child_weight': 6}. Best is trial 4 with value: 26.460696860795544.\n",
      "[I 2025-09-26 11:16:07,836] Trial 5 finished with value: 26.460426089368262 and parameters: {'max_depth': 5, 'min_child_weight': 8}. Best is trial 5 with value: 26.460426089368262.\n",
      "[I 2025-09-26 11:16:24,009] Trial 6 finished with value: 26.460982741670826 and parameters: {'max_depth': 8, 'min_child_weight': 20}. Best is trial 5 with value: 26.460426089368262.\n",
      "[I 2025-09-26 11:16:36,146] Trial 7 finished with value: 26.46063317486096 and parameters: {'max_depth': 6, 'min_child_weight': 19}. Best is trial 5 with value: 26.460426089368262.\n",
      "[I 2025-09-26 11:16:47,521] Trial 8 finished with value: 26.460696860795544 and parameters: {'max_depth': 3, 'min_child_weight': 6}. Best is trial 5 with value: 26.460426089368262.\n",
      "[I 2025-09-26 11:16:57,718] Trial 9 finished with value: 26.46045478054566 and parameters: {'max_depth': 4, 'min_child_weight': 16}. Best is trial 5 with value: 26.460426089368262.\n",
      "[I 2025-09-26 11:17:08,753] Trial 10 finished with value: 26.46038323380796 and parameters: {'max_depth': 5, 'min_child_weight': 11}. Best is trial 10 with value: 26.46038323380796.\n",
      "[I 2025-09-26 11:17:19,821] Trial 11 finished with value: 26.460398546415632 and parameters: {'max_depth': 5, 'min_child_weight': 12}. Best is trial 10 with value: 26.46038323380796.\n",
      "[I 2025-09-26 11:17:31,737] Trial 12 finished with value: 26.46062270839435 and parameters: {'max_depth': 6, 'min_child_weight': 12}. Best is trial 10 with value: 26.46038323380796.\n",
      "[I 2025-09-26 11:17:42,977] Trial 13 finished with value: 26.460398546415632 and parameters: {'max_depth': 5, 'min_child_weight': 12}. Best is trial 10 with value: 26.46038323380796.\n",
      "[I 2025-09-26 11:17:53,997] Trial 14 finished with value: 26.460360361529787 and parameters: {'max_depth': 5, 'min_child_weight': 15}. Best is trial 14 with value: 26.460360361529787.\n",
      "[I 2025-09-26 11:18:07,590] Trial 15 finished with value: 26.46062319131507 and parameters: {'max_depth': 7, 'min_child_weight': 15}. Best is trial 14 with value: 26.460360361529787.\n",
      "[I 2025-09-26 11:18:17,743] Trial 16 finished with value: 26.46047298132305 and parameters: {'max_depth': 4, 'min_child_weight': 15}. Best is trial 14 with value: 26.460360361529787.\n",
      "[I 2025-09-26 11:18:28,051] Trial 17 finished with value: 26.46051056185255 and parameters: {'max_depth': 4, 'min_child_weight': 10}. Best is trial 14 with value: 26.460360361529787.\n",
      "[I 2025-09-26 11:18:41,620] Trial 18 finished with value: 26.46076735220212 and parameters: {'max_depth': 7, 'min_child_weight': 17}. Best is trial 14 with value: 26.460360361529787.\n",
      "[I 2025-09-26 11:19:06,418] Trial 19 finished with value: 26.462698931393316 and parameters: {'max_depth': 10, 'min_child_weight': 14}. Best is trial 14 with value: 26.460360361529787.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Best Parameters: {'max_depth': 5, 'min_child_weight': 10, 'gamma': 0.1, 'reg_alpha': 1, 'reg_lambda': 5, 'subsample': 0.8, 'colsample_bytree': 0.8, 'objective': 'reg:squarederror', 'eval_metric': 'rmse', 'early_stopping_rounds': 500}\n"
     ]
    }
   ],
   "source": [
    "#xgboost调参\n",
    "def objective(trial):\n",
    "    X_train=train_df[feature_selected]\n",
    "    y_train=train_df['BeatsPerMinute']\n",
    "\n",
    "    params = {\n",
    "        \n",
    "      # 第一优先级\n",
    "        'learning_rate': 0.01,\n",
    "        'n_estimators':1940,\n",
    "         'max_depth': 5, 'min_child_weight': 15,\n",
    "        'gamma': trial.suggest_float('gamma', 0, 0.5, step=0.05),\n",
    "        'reg_alpha': trial.suggest_float('reg_alpha', 0, 10, step=0.5),\n",
    "        'reg_lambda': trial.suggest_float('reg_lambda', 0.1, 10, step=0.5),\n",
    "        'subsample': 0.8,\n",
    "        'colsample_bytree': 0.8,\n",
    "        'objective': 'reg:squarederror',\n",
    "        'eval_metric': 'rmse',\n",
    "        'early_stopping_rounds':500,\n",
    "        'tree_method':\"hist\",  # 必须使用非弃用的树方法\n",
    "        'device':\"cuda\",       # 启用CUDA加速\n",
    "        #'predictor':\"gpu_predictor\"  # 可选，GPU预测加速\n",
    "        #'device': 'cuda',  # 替代原gpu_hist参数\n",
    "        #'predictor': 'gpu_predictor',  # 维持GPU预测\n",
    "        #'gpu_id': 0  # 指定设备编号\n",
    "        }\n",
    "\n",
    "        # 第二优先级\n",
    "       \n",
    "        #\n",
    "        ## 第三优先级\n",
    "        #'gamma': trial.suggest_float('gamma', 0, 0.5, step=0.05),\n",
    "        #'reg_alpha': trial.suggest_float('reg_alpha', 0, 10, step=0.5),\n",
    "        #'reg_lambda': trial.suggest_float('reg_lambda', 0.1, 10, step=0.5),\n",
    "        #\n",
    "        ## 第四优先级\n",
    "        #'subsample': trial.suggest_float('subsample', 0.6, 1.0, step=0.05),\n",
    "        #'colsample_bytree': trial.suggest_float('colsample_bytree', 0.6, 1.0, step=0.05),\n",
    "        \n",
    "\n",
    "\n",
    "    #            'learning_rate': 0.05,\n",
    "    #\n",
    "    #'n_estimators': 300,\n",
    "\n",
    "           \n",
    "        \n",
    "    \n",
    "    #if params['num_leaves'] > 2 ** params['max_depth']:\n",
    "    #    params['num_leaves'] = 2 ** params['max_depth'] - 1\n",
    "    #params['num_leaves'] = min(params['num_leaves'], 2 ** params['max_depth'] - 1)\n",
    "    kf = KFold(n_splits=5, shuffle=True, random_state=42)\n",
    "    val_mses = []\n",
    "    \n",
    "    for train_idx, val_idx in kf.split(X_train):\n",
    "        X_tr, X_val = X_train.iloc[train_idx], X_train.iloc[val_idx]\n",
    "        y_tr, y_val = y_train.iloc[train_idx], y_train.iloc[val_idx]\n",
    "\n",
    "        model =XGBRegressor(**params)\n",
    "        model.fit(X_tr, y_tr, eval_set=[(X_tr,y_tr),(X_val, y_val)], verbose=0)\n",
    "        val_pred = model.predict(X_val)\n",
    "        rmse = np.sqrt(mean_squared_error(y_val, val_pred))\n",
    "        val_mses.append(rmse)\n",
    "    \n",
    "    return np.mean(val_mses)\n",
    "\n",
    "# 运行Optuna优化\n",
    "study = optuna.create_study(direction='minimize')\n",
    "study.optimize(objective, n_trials=20)\n",
    "\n",
    "# 使用最佳参数训练最终模型\n",
    "best_params = study.best_params\n",
    "\n",
    "# 输出最佳参数（浮点数保留两位小数）\n",
    "best_params = {k: round(v, 2) if isinstance(v, float) else v \n",
    "               for k, v in study.best_params.items()}\n",
    "best_params.update({\n",
    "          # 辅助参数\n",
    "        'max_depth': 5,\n",
    "        'min_child_weight':10,\n",
    "        'gamma': 0.1,\n",
    "        'reg_alpha': 1,\n",
    "        'reg_lambda': 5,\n",
    "        'subsample': 0.8,\n",
    "        'colsample_bytree': 0.8,\n",
    "        'objective': 'reg:squarederror',\n",
    "        'eval_metric': 'rmse',\n",
    "        'early_stopping_rounds':500,\n",
    "        #'tree_method': 'gpu_hist',\n",
    "        #'predictor': 'gpu_predictor',\n",
    "        \n",
    "})\n",
    "print(\"Best Parameters:\", best_params)\n",
    "\n",
    "\n",
    "\n",
    "#X_train=train_df[feature_selected]\n",
    "#y_train=train_df['BeatsPerMinute']\n",
    "#final_model = XGBRegressor(**best_params)\n",
    "#final_model.fit(X_train, y_train)\n",
    "#\n",
    "## 测试集预测\n",
    "#test_preds = final_model.predict(X_test)\n",
    "#\n",
    "## 保存结果\n",
    "#result = pd.DataFrame({\n",
    "#    'id': test_df['id'],\n",
    "#    'BeatsPerMinute': test_preds\n",
    "#})\n",
    "#result.to_csv('optimized_submission.csv', index=False)\n",
    "#"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "9c64b5c2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'learning_rate': 0.05,\n",
       " 'n_estimators': 1450,\n",
       " 'max_depth': 5,\n",
       " 'num_leaves': 179}"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "best_params"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "base",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
